﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using AgencyEntityLib.BaseEntity;
using Ecopsy.Tools;
using Ecopsy.DataTier;
using AgencyEntityLib.Context;


namespace AgencyEntityLib.BaseEntity
{
    public class wsDictionary:EntitySingle 
    {

        /// <summary>
        /// сервис по управлению справочниками
        /// </summary>
        public wsDictionary()
        {
            //Uncomment the following line if using designed components 
            //InitializeComponent(); 
        }

        /// <summary>
        /// Вернуть ветку деревянного справочника
        /// </summary>
        /// <param name="FolderId">папка справочника  </param>
        /// <param name="TreeDictionaryID">тип справочника </param>
        /// <param name="BranchID">ветка справочника</param>
        /// <returns></returns>
      
        public TreeDictionaryItem GetTreeDictionaryBranch(string FolderId,
                                                          string TreeDictionaryID,
                                                          string BranchID)
        {
            if (null == FolderId) throw new ArgumentNullException("FolderId");
            if (null == TreeDictionaryID) throw new ArgumentNullException("TreeDictionaryID");
            if (null == BranchID) throw new ArgumentNullException("BranchID");

            try
            {
                TreeEntitySingle Dict = GetTreeDictionary(FolderId, TreeDictionaryID);
                return (TreeDictionaryItem)Dict.Find(BranchID);
            }
            catch
            {
                return null;
            }

        }


        /// <summary>
        /// Вернуть справочник из заданной папки
        /// </summary>
        /// <param name="FolderId">папка справочника  </param>
        /// <param name="TreeDictionaryID">тип справочника</param>
        /// <returns></returns>
       
        public TreeDictionaryItem GetTreeDictionary(string FolderId, string ID)
        {

            if (null == FolderId) throw new ArgumentNullException("FolderId");
            if (null == ID) throw new ArgumentNullException("ID");

            try
            {
                TreeDictionaryFolder f = GetTreeDictionaryFolder(FolderId);
                TreeDictionaryItem d = (TreeDictionaryItem)f.ListTreeDictionaryItems[ID];
                return d;
            }
            catch
            {
                throw;
            }

        }

        /// <summary>
        /// Вернуть справочники заданного типа  из папки.
        /// </summary>
        /// <param name="FolderId">Папка </param>
        /// <param name="DictionaryTypeId"> тип справочника</param>    
        /// <returns></returns>

        public TreeDictionaryItem[] GetTreeDictionaryOfType(string FolderId, string DictionaryTypeId)
        {
            if (null == FolderId) throw new ArgumentNullException("FolderId");
            if (null == DictionaryTypeId) throw new ArgumentNullException("DictionaryTypeId");

            try
            {
                //достаем тип справочника
                TreeDictionaryFolder f = GetTreeDictionaryFolder(FolderId);

                // Формируем массив объектов
                List<TreeDictionaryItem> r = f.ListTreeDictionaryItems.ToList<TreeDictionaryItem>();

                //отбираем
                var result =
                    from
                        n in r
                    where
                         n.TypeID == DictionaryTypeId
                    orderby n.Name

                    select n;

                return result.ToArray<TreeDictionaryItem>();
            }
            catch
            {
                throw;

            }

        }


        /// <summary>
        /// Список vTreeDictionaryType 
        /// </summary>
        /// <returns></returns>
     
        public TreeDictionaryTypeList GetTreeDictionaryTypeList()
        {
            TreeDictionaryTypeList l = new TreeDictionaryTypeList();
            l.Load();
            return l;
        }

        /// <summary>
        /// Создает сравочник - для всех справочников кроме типа - Адресная программа - ид справочника совпадает с ид типа справочника.    
        /// </summary>
        /// <param name="FolderId"></param>
        /// <param name="TreeDictionaryType"></param>
        /// <param name="Name"></param>
        /// <returns></returns>
      
        public TreeDictionaryItem CreateTreeDictionary(string FolderId,
                                                        string TreeDictionaryType,
                                                        string Name)
        {
            if (null == FolderId) throw new ArgumentNullException("FolderId");
            if (null == TreeDictionaryType) throw new ArgumentNullException("TreeDictionaryType");
            if (null == Name) throw new ArgumentNullException("Name");

            try
            {
                TreeDictionaryFolder f = GetTreeDictionaryFolder(FolderId);
                string s = (TreeDictionaryType == AgencyLib_GlobalConstants.TreeDictionary_AdressProgram ? Guid.NewGuid().ToString() : TreeDictionaryType);
                TreeDictionaryItem d = new TreeDictionaryItem { ID = s, TypeID = TreeDictionaryType, Name = Name };

                f.ListTreeDictionaryItems.Add(d);
                // сохранить изменения в папке
                f.Save();
                return d;
            }
            catch
            {
                throw;
            }

        }

        const string key = "KeyTreeFolder";
        /// <summary>
        /// Вернуть папку с древовидными справочниками
        /// </summary>
        /// <param name="FolderId"></param>
        /// <returns></returns>
        
        public TreeDictionaryFolder GetTreeDictionaryFolder(string FolderId)
        {


            if (null == FolderId) throw new ArgumentNullException("FolderId");

            if (!CacheTools.IsCacheObject(key + FolderId))
            {
                TreeDictionaryFolder f = new TreeDictionaryFolder { ID = FolderId };
                f.Load();
                CacheTools.SetCacheObject(key + FolderId, f);
                return f;
            }
            return (TreeDictionaryFolder)CacheTools.GetCacheObect(key + FolderId);

        }

        /// <summary>
        ///  сбросить  кэш  справочников 
        /// </summary>
        public static void ResetCacheTreeDictionaryFolder(string FolderId)
        {
            CacheTools.ResetCache(key + FolderId);
        }


        /// <summary>
        /// Вернуть ветку дереванного справочника. возвращает обновленную ветку
        /// </summary>
        /// <param name="FolderId"></param>
        /// <param name="TreeDictionaryID"></param>
        /// <param name="BranchID"></param>
        /// <returns></returns>
        
        public void UpdateTreeDictionaryBranch(string FolderId,
                                               string TreeDictionaryID,
                                               string BranchID,
                                               string TextValue)
        {
            if (null == FolderId) throw new ArgumentNullException("FolderId");
            if (null == TreeDictionaryID) throw new ArgumentNullException("TreeDictionaryID");
            if (null == BranchID) throw new ArgumentNullException("BranchID");
            if (null == TextValue) throw new ArgumentNullException("TextValue");
            try
            {

                TreeDictionaryItem br = GetTreeDictionaryBranch(FolderId, TreeDictionaryID, BranchID);
                br.Name = TextValue;                
                GetTreeDictionaryFolder(FolderId).Save();
            }
            catch
            {
                throw;
            }

        }


        /// <summary>
        /// Добавить ветку в заданный 
        /// </summary>
        /// <param name="FolderId"></param>
        /// <param name="TreeDictionaryID"></param>
        /// <param name="BranchID"></param>
        /// <param name="BranchName"></param>
        /// <returns></returns>
        
        public TreeDictionaryItem AddTreeDictionaryBranch
            (string FolderId,
             string TreeDictionaryID,
             string ParentBranchID,
            string BranchName
            )
        {
            if (null == FolderId) throw new ArgumentNullException("FolderId");
            if (null == TreeDictionaryID) throw new ArgumentNullException("TreeDictionaryID");
            if (null == ParentBranchID) throw new ArgumentNullException("ParentBranchID");
            if (null == BranchName) throw new ArgumentNullException("BranchName");

            try
            {
                TreeDictionaryItem Parent = GetTreeDictionaryBranch(FolderId, TreeDictionaryID, ParentBranchID);
                TreeDictionaryItem b = new TreeDictionaryItem { ID = Guid.NewGuid().ToString(), Name = BranchName };
                Parent.ChildNodes.Add(b);
                GetTreeDictionaryFolder(FolderId).Save();
                CacheTools.ResetCache(FolderId);
                return b;
            }
            catch
            {
                return null;
            }

        }

        
        public void RemoveTreeDictionaryBranch(string FolderId,
                                                string TreeDictionaryID,
                                                string BranchID)
        {
            if (null == FolderId) throw new ArgumentNullException("FolderId");
            if (null == TreeDictionaryID) throw new ArgumentNullException("TreeDictionaryID");
            if (null == BranchID) throw new ArgumentNullException("BranchID");

            try
            {
                TreeDictionaryItem br = GetTreeDictionaryBranch(FolderId, TreeDictionaryID, BranchID);
                br.DestroyMySelf();
                GetTreeDictionaryFolder(FolderId).Save();
                ResetCacheTreeDictionaryFolder(FolderId);
            }
            catch
            {
                throw;
            }

        }

        /// <summary>
        /// Вернуть справочник хранящийся в табичке Dictionary
        /// </summary>
        /// <param name="DictionaryTypeID"></param>
        /// <returns></returns>
        
        public List<DictionaryItem> GetDictionary(string DictionaryTypeID)
        {
            if (null == DictionaryTypeID) throw new ArgumentNullException("DictionaryTypeID");
            DictionaryItemList list = new DictionaryItemList();
            list.DictionaryTypeID = DictionaryTypeID;
            list.Load();
            return list.ToList<DictionaryItem>();

        }



    }
}
